Skip to main content
Version: 11.0

Python SDK

Purpose

The Insights Python SDK exports several classes and methods that you need when doing custom device discovery through Python.

Location

The python files constituting the Insights Python SDK are located on the DC node at the following path:

/opt/meridian/dc/embedded/lib/python3.9/site-packages/meridian_workers/celeryd/external_collector/external_discovery_payload/

Usage

A single Python script allows you to describe a single custom device by setting values to the classes' properties.

Describing a Compute Device

Take these actions to create the device description:

The following example describes a VM running on a VMware hypervisor.

from meridian_workers.celeryd.external_collector.external_discovery_payload.payload_construction import Payload
from meridian_workers.celeryd.external_collector.external_discovery_payload.info import Info
from meridian_workers.celeryd.external_collector.external_discovery_payload.compute_device import ComputeDevice
from meridian_workers.celeryd.external_collector.external_discovery_payload.vm_detail_info import VmDetailInfo
from meridian_workers.celeryd.external_collector.external_discovery_payload.ip_mac_fqdn import IpMacFqdn
from meridian_workers.celeryd.external_collector.external_discovery_payload.mounted_volume import MountedVolume
from meridian_workers.celeryd.external_collector.external_discovery_payload.cpu_info import CpuInfo


info_obj = Info()

info_obj.ip_address = "198.51.100.1"
info_obj.hostname = "qa201-nce1"
info_obj.vendor = "VMWARE"
info_obj.platform = "LINUX"
info_obj.platformType = "CENTOS LINUX"
info_obj.version = "7.9.2009 (CORE)"
info_obj.serial_number = "VMWARE-56 4D 84 AE 0F 8A BA A0-A2 1F 9F 09 A9 7B 66 4B"
info_obj.model = "VMWARE VIRTUAL PLATFORM"
info_obj.is_virtual = 1
info_obj.device_type = "COMPUTE"
info_obj.device_subtype = "VM"

compute_obj = ComputeDevice()
compute_obj.vmDetailInfo = VmDetailInfo()

ip_mac_fqdn = IpMacFqdn()
ip_mac_fqdn.ipv4Addr = "198.51.100.1"
ip_mac_fqdn.phyAddr = "0150569D7A3A"

compute_obj.vmDetailInfo.ipMacFqdn = ip_mac_fqdn
compute_obj.vmDetailInfo.coresPerSocket = 4

cpu_info = CpuInfo()
cpu_info.vendor = "GenuineIntel"
cpu_info.modelName = "Intel(R) Xeon(R) CPU E5-2665 0 @ 2.40GHz"
cpu_info.processorCount = 16

compute_obj.vmDetailInfo.cpuInfo = cpu_info

compute_obj.vmDetailInfo.cpuMHz = 2400
compute_obj.vmDetailInfo.cpuTotal = 16
compute_obj.vmDetailInfo.kernelVersion = "3.10.0-1062.el7.x86_64"
compute_obj.vmDetailInfo.memoryMB = 32009

mounted_volumn_1 = MountedVolume()
mounted_volumn_1.volumeName = "devtmpfs"
mounted_volumn_1.sizeGB = 16

mounted_volumn_2 = MountedVolume()
mounted_volumn_2.volumeName = "tmpfs"
mounted_volumn_2.sizeGB = 3.2

compute_obj.vmDetailInfo.mountedVolume = [mounted_volumn_1, mounted_volumn_2]

payload = Payload()

payload.info = info_obj
payload.data = compute_obj

final_payload = payload.serialize()

print(final_payload)

Describing a Network Device

Take these actions to create the device description:

The following example describes a network switch.

from meridian_workers.celeryd.external_collector.external_discovery_payload.network_device import NetworkDevice
from meridian_workers.celeryd.external_collector.external_discovery_payload.info import Info
from meridian_workers.celeryd.external_collector.external_discovery_payload.interfaces import Interfaces
from meridian_workers.celeryd.external_collector.external_discovery_payload.ifx_switch_port import IfxSwitchport
from meridian_workers.celeryd.external_collector.external_discovery_payload.ifname_index_map import IfNameIndexMap
from meridian_workers.celeryd.external_collector.external_discovery_payload.port_channel_summary import PortChannelSummary
from meridian_workers.celeryd.external_collector.external_discovery_payload.vm_detail_info import VmDetailInfo
from meridian_workers.celeryd.external_collector.external_discovery_payload.ip_mac_fqdn import IpMacFqdn
from meridian_workers.celeryd.external_collector.external_discovery_payload.mac_address_table import macAddressTable
from meridian_workers.celeryd.external_collector.external_discovery_payload.interface_neighbor_lldp import InterfaceNeighborsLLDP
from meridian_workers.celeryd.external_collector.external_discovery_payload.interface_neighbor_cdp import InterfaceNeighborsCDP
from meridian_workers.celeryd.external_collector.external_discovery_payload.arp_table import ArpTable
from meridian_workers.celeryd.external_collector.external_discovery_payload.vrf_name import VrfName
from meridian_workers.celeryd.external_collector.external_discovery_payload.payload_construction import Payload
from meridian_workers.celeryd.external_collector.external_discovery_payload.customer_info import CustomerInfo


# Add basic info of device which is available
info_obj = Info()
info_obj.ip_address = "203.0.113.1"
info_obj.hostname = "cosmos"
info_obj.vendor = "VMWARE"
info_obj.platform = "linux"
info_obj.platformType = "CENT OS LINUX"
info_obj.version = "6.1(FINAL)"
info_obj.serial_number = "VMware-42 1f 1f c7 1c 03 c2 d9-4d 8c d7 88 8e a5 99 1a"
info_obj.model = "VMware Virtual Platform"
info_obj.is_virtual = 1
info_obj.device_type = "NETWORK"
info_obj.device_subtype = "SWITCH"
info_obj.parents = []

# Add Site and Org to customer_info
customer_info = CustomerInfo()
customer_info.site = "2d051e90-c879-4f15-8833-0eb1d58bf86d:EAST"
customer_info.organization = "3cba0785-be2d-4163-b1f6-9bb37f0a19c1:EXAMPLE"

network_interface = Interfaces()
network_interface.bandwidth = "2000"
network_interface.ifxGlobalType = "Port-channel"
network_interface.ifxName = "Port-channel18"
network_interface.linkState = "up"
network_interface.normalize = True
network_interface.phyAddr = "84802d5c4202"
network_interface.portNo = "18"

ifx_switch_port = IfxSwitchport()
ifx_switch_port.ifxLayerType = "L2"
ifx_switch_port.ifxName = "Port-channel18"
ifx_switch_port.ifxSwitchportMode = "trunk"
ifx_switch_port.nativeVlan = "1"
ifx_switch_port.normalize = True
ifx_switch_port.vlanList = [20, 30, 91, 92]

ifname_index_map = IfNameIndexMap()
ifname_index_map.ifIndex = "5024"
ifname_index_map.ifName = "Port-channel24"

port_channel_summary = PortChannelSummary()
port_channel_summary.ifxName = "gigabitEthernet1/0/2"
port_channel_summary.pcGroupNumber = "18"
port_channel_summary.pcMode = "LACP"

vm_detail_info = VmDetailInfo()
vm_detail_info.runningConfiguration = "Building configuration...\n\nCurrent configuration : 9266 bytes\n!\n! Last configuration change at 07:25:06 PST Thu Jan 14 2021 by rsadmin\n! NVRAM config last updated at 17:14:07 PST Tue Dec 15 2020 by rsadmin\n!"

ip_mac_fqdn = IpMacFqdn()
ip_mac_fqdn.ipv4Addr = "203.0.113.1"
ip_mac_fqdn.phyAddr = "84902D5C4239"

mac_address_table = macAddressTable()
mac_address_table.entryType = "DYNAMIC"
mac_address_table.ifxName = "Port-channel18"
mac_address_table.macAddress = "01260bf1f012"
mac_address_table.normalize = True
mac_address_table.vlanId = ["30"]

interface_neighbors_lldp = InterfaceNeighborsLLDP()
interface_neighbors_lldp.ifxName = "gigabitEthernet1/0/7"
interface_neighbors_lldp.neighborIfxName = "ethernet1/7"
interface_neighbors_lldp.neighborIpAddrList = ["198.51.100.2"]
interface_neighbors_lldp.neighborName = "fs5678"

interface_neighbors_cdp = InterfaceNeighborsCDP()
interface_neighbors_cdp.ifxName = "gigabitEthernet1/0/2"
interface_neighbors_cdp.neighborIfxName = "ethernet1/8"
interface_neighbors_cdp.neighborIpAddrList = ["198.51.100.3", "233.252.0.1"]
interface_neighbors_cdp.neighborName = "fs5679"

arp_table = ArpTable()
arp_table.ifxName = "Vlan91"
arp_table.macAddress = "012a6af94441"

vrf_name = VrfName()
vrf_name.exitIntf = ["management1", "management1", "management1", "management1"]
vrf_name.ipAddress = ["198.51.100.4", "198.51.100.5", "198.51.100.6", "198.51.100.7"]
vrf_name.phyAddress = ["8c95f3a28dc6", "94802d5c4239", "94802d5c28b9", "012a6afa8681"]
vrf_name.vrfName = "management"

network_obj = NetworkDevice()
network_obj.interfaces = [network_interface]
network_obj.ifxSwitchport = [ifx_switch_port]
network_obj.interfaces_mgmt0 = []
network_obj.ifNameIndexMap = [ifname_index_map]
network_obj.portChannelSummary = [port_channel_summary]
network_obj.vmDetailInfo = vm_detail_info
network_obj.ipMacFqdn = ip_mac_fqdn
network_obj.macAddressTable = [mac_address_table]
network_obj.interfaceNeighborsLLDP = [interface_neighbors_lldp]
network_obj.interfaceNeighborsCDP = [interface_neighbors_cdp]
network_obj.arpTable = [arp_table]
network_obj.vrfName = [vrf_name]

payload = Payload()

#Assign info, data and customer_info to Payload Object
payload.info = info_obj
payload.data = network_obj
payload.customer_info = customer_info

final_payload = payload.serialize()

# This should output JSON with info, data and customer_info keys and specified keys
print(final_payload)

Describing a Storage Device

Take these actions to create the device description:

  • Import the Info class.
  • Instantiate Info and set the object's properties. These represent the basic device description.
  • Initialize a dictionary using the MapStorage class. It will store all the storage's components like controllers, LUNs, storage groups, ports, and pools.
  • For each of the storage device's components, import and instantiate the main class for the Storage device type: Storage:
    • Use the StorageInfo class to describe the info property.
    • Use the StorageDetails class to describe the details property.
    • Use the relatedEntities property to describe the relationships between the various device components (see the example).
  • Import and instantiate any subclasses needed for building the detailed description of the device type:
  • Finally, import and instantiate the Payload class to create the payload from the device's basic description and detailed data.

The following example describes a Dell EMC storage controller with all its components.

import json

from meridian_workers.celeryd.external_collector.external_discovery_payload.customer_info import CustomerInfo
from meridian_workers.celeryd.external_collector.external_discovery_payload.info import Info
from meridian_workers.celeryd.external_collector.external_discovery_payload.payload_construction import Payload
from meridian_workers.celeryd.external_collector.external_discovery_payload.storage.storage_details import Storage, \
StorageInfo, StorageDetails, ControllerInterfaces, MapStorage, HBASPPair

if __name__ == "__main__":
storage_map = MapStorage()

# ---------- Controller
controller = Storage()

# Controller Info
controller_info = StorageInfo()
controller_info.hostName = "emc b"
controller_info.vendor = "EMC CORPORATION"
controller_info.platform = "VNX-BLOCK-OPERATING-ENVIRONMENT"
controller_info.isVirtual = "0"
controller_info.discoveredIpAddr = "198.51.100.21"
controller_info.devType = "STORAGE"
controller_info.devSubType = "CONTROLLER"
controller_info.model = "VNX5200"
controller_info.serialNumber = "CF2BN142000223"
# Parents is a list of hostname/serial, if multiple add loop to add multiple parents
controller_info.parents = "emcvnx1"

# Controller Details
controller_details = StorageDetails()
controller_details.serialNumber = "CF2BN142000223"
controller_details.statisticsLogging = "ON"

# Controller Interface1
controller_interfaces = ControllerInterfaces()
controller_interfaces.ifxName = "emc b0"
controller_interfaces.wwnn = "5006016088604403"
controller_interfaces.wwpn = "5006016808604403"
controller_interfaces.macAddress = ""
controller_interfaces.linkStatus = "Down"
controller_interfaces.portStatus = "DISABLED"

# Controller Interface2
controller_interfaces2 = ControllerInterfaces()
controller_interfaces2.ifxName = "emc b1"
controller_interfaces2.wwnn = "5006016088604402"
controller_interfaces2.wwpn = "5006016808604402"
controller_interfaces2.linkStatus = "Up"
controller_interfaces2.portStatus = "ONLINE"
controller_interfaces2.macAddress = "01:60:16:4E:33:B2"

controller.ifxInfo = [controller_interfaces, controller_interfaces2]
# Controller
controller.info = controller_info
controller.details = controller_details

controller.relatedEntities = {"HYPERVISOR": ["esxi-2.in.example.com"], "STORAGEGROUP": ["fs_storage_3"], "STORAGE": ["emcvnx1"]}
storage_map.map_component("controllers", controller)


# ---------- Controller 2
controller2 = Storage()

# Controller 2 Info
controller_info2 = StorageInfo()
controller_info2.hostName = "emc a"
controller_info2.vendor = "EMC CORPORATION"
controller_info2.platform = "VNX-BLOCK-OPERATING-ENVIRONMENT"
controller_info2.isVirtual = "0"
controller_info2.discoveredIpAddr = "198.51.100.20"
controller_info2.devType = "STORAGE"
controller_info2.devSubType = "CONTROLLER"
controller_info2.model = "VNX5200"
controller_info2.serialNumber = "CF2BN142000300"
# Parents is a list of hostname/serial, if multiple add loop to add multiple parents
controller_info2.parents = "emcvnx1"

# Controller Details
controller_details2 = StorageDetails()
controller_details2.serialNumber = "CF2BN142000300"
controller_details2.statisticsLogging = "ON"

# Controller Interface1
controller_interfaces = ControllerInterfaces()
controller_interfaces.ifxName = "emc a0"
controller_interfaces.wwnn = "5006016088604404"
controller_interfaces.wwpn = "5006016808604404"
controller_interfaces.macAddress = ""
controller_interfaces.linkStatus = "Down"
controller_interfaces.portStatus = "DISABLED"

# Controller Interface2
controller_interfaces2 = ControllerInterfaces()
controller_interfaces2.ifxName = "emc a1"
controller_interfaces2.wwnn = "5006016088604405"
controller_interfaces2.wwpn = "5006016808604405"
controller_interfaces2.linkStatus = "Up"
controller_interfaces2.portStatus = "ONLINE"
controller_interfaces2.macAddress = "01:60:16:4E:33:B3"

controller2.ifxInfo = [controller_interfaces, controller_interfaces2]
# Controller
controller2.info = controller_info2
controller2.details = controller_details2

controller2.relatedEntities = {"HYPERVISOR": ["esxi-2.in.example.com"], "STORAGEGROUP": ["fs_storage_3"],
"STORAGE": ["emcvnx1"]}
storage_map.map_component("controllers", controller2)

# Port ----------

port = Storage()

port_details = StorageDetails()
port_details.spName = "emc b"
port_details.phyPortId = "0"

port_info = StorageInfo()
port_info.hostName = "emc b0"
port_info.uuid = "50:06:01:60:88:60:44:03:50:06:01:68:08:60:44:03"
port_info.devType = "STORAGE"
port_info.isVirtual = "1"
port_info.devSubType = "PORT"
port_info.vendor = "EMC CORPORATION"
port_info.platform = "VNX-BLOCK-OPERATING-ENVIRONMENT"
port_info.model = "VNX5200"
port_info.parents = "emc b"

port.details = port_details
port.info = port_info

port.relatedEntities = {"CONTROLLER": ["emc b"], "HYPERVISOR": ["esxi-2.in.example.com"], "STORAGEGROUP": ["fs_storage_3"], "STORAGE": ["emcvnx1"]}
storage_map.map_component("ports", port)

# Port 2 ----------

port2 = Storage()

port_details2 = StorageDetails()
port_details2.spName = "emc a"
port_details2.phyPortId = "1"

port_info2 = StorageInfo()
port_info2.hostName = "emc a0"
port_info2.uuid = "50:06:01:60:88:60:44:03:50:06:01:68:08:60:44:04"
port_info2.devType = "STORAGE"
port_info2.isVirtual = "1"
port_info2.devSubType = "PORT"
port_info2.vendor = "EMC CORPORATION"
port_info2.platform = "VNX-BLOCK-OPERATING-ENVIRONMENT"
port_info2.model = "VNX5200"
port_info2.parents = "emc a"

port2.details = port_details2
port2.info = port_info2

port2.relatedEntities = {"CONTROLLER": ["emc a"], "HYPERVISOR": ["esxi-2.in.example.com"],
"STORAGEGROUP": ["fs_storage_3"], "STORAGE": ["emcvnx1"]}
storage_map.map_component("ports", port2)

# Lun ----------

lun = Storage()

lun_info = StorageInfo()
lun_info.lunId = 13
lun_info.uuid = "60:06:01:60:DF:40:39:00:D8:81:81:6A:1C:FF:E4:11"
lun_info.devType = "STORAGE"
lun_info.devSubType = "LUN"
lun_info.hostName = "esxi2datastore"
lun_info.isVirtual = "1"
lun_info.vendor = "EMC CORPORATION"
lun_info.platform = "VNX-BLOCK-OPERATING-ENVIRONMENT"
lun_info.model = "VNX5200"
lun_info.parents = "fs_pool_3"

lun_detail = StorageDetails()
lun_detail.lunWwn = "60060160df403900d881816a1cffe411"
lun_detail.storageGroups = ["fs_storage_3"]
lun_detail.currentUser = "emc b"

lun.info = lun_info
lun.details = lun_detail
lun.relatedEntities = {"CONTROLLER": ["emc b"], "HYPERVISOR": ["esxi-2.in.example.com"], "STORAGEPOOL": ["fs_pool_3"],
"STORAGEGROUP": ["fs_storage_3"], "STORAGE": ["emcvnx1"]}
storage_map.map_component("luns", lun)


lun2 = Storage()

lun_info2 = StorageInfo()
lun_info2.lunId = 12
lun_info2.uuid = "60:06:01:60:DF:40:39:11:D8:81:81:6A:1C:F1:E4:00"
lun_info2.devType = "STORAGE"
lun_info2.devSubType = "LUN"
lun_info2.hostName = "esxi2datastore_2"
lun_info2.isVirtual = "1"
lun_info2.vendor = "EMC CORPORATION"
lun_info2.platform = "VNX-BLOCK-OPERATING-ENVIRONMENT"
lun_info2.model = "VNX5200"
lun_info2.parents = "fs_pool_4"

lun_detail2 = StorageDetails()
lun_detail2.lunWwn = "60060160df403900d881816a1cffe412"
lun_detail2.storageGroups = ["storage4"]
lun_detail2.currentUser = "emc a"

lun2.info = lun_info2
lun2.details = lun_detail2
lun2.relatedEntities = {"CONTROLLER": ["emc a"], "HYPERVISOR": ["esxi-2.in.example.com"], "STORAGEPOOL": ["fs_pool_4"],
"STORAGEGROUP": ["storage4"], "STORAGE": ["emcvnx1"]}
storage_map.map_component("luns", lun2)

# Pools ----------

pool = Storage()

pool_details = StorageDetails()
pool_details.raidType = "r_5"
pool_details.lunList = ["9", "11", "8"]
pool_details.boundDisks = ["0_0_4", "0_0_8", "0_0_5", "0_0_7", "0_0_6"]

pool_info = StorageInfo()
pool_info.hostName = "fs_pool_3"
pool_info.devType = "STORAGE"
pool_info.isVirtual = "1"
pool_info.devSubType = "STORAGEPOOL"
pool_info.vendor = "EMC CORPORATION"
pool_info.platform = "VNX-BLOCK-OPERATING-ENVIRONMENT"
pool_info.model = "VNX5200"
pool_info.parents = "emcvnx1"

pool.details = pool_details
pool.info = pool_info

pool.relatedEntities = {"HYPERVISOR": ["esxi-2.in.example.com"],
"STORAGEGROUP": ["fs_storage_3"], "STORAGE": ["emcvnx1"]}
storage_map.map_component("pools", pool)


pool2 = Storage()

pool_details2 = StorageDetails()
pool_details2.raidType = "r_6"
pool_details2.lunList = ["10", "12", "7"]
pool_details2.boundDisks = ["0_0_3", "0_0_9", "0_0_4", "0_0_8", "0_0_5"]

pool_info2 = StorageInfo()
pool_info2.hostName = "fs_pool_4"
pool_info2.devType = "STORAGE"
pool_info2.isVirtual = "1"
pool_info2.devSubType = "STORAGEPOOL"
pool_info2.vendor = "EMC CORPORATION"
pool_info2.platform = "VNX-BLOCK-OPERATING-ENVIRONMENT"
pool_info2.model = "VNX5200"
pool_info2.parents = "emcvnx1"

pool2.details = pool_details2
pool2.info = pool_info2

pool2.relatedEntities = {"HYPERVISOR": ["esxi-2.in.example.com"],
"STORAGEGROUP": ["storage4"], "STORAGE": ["emcvnx1"]}
storage_map.map_component("pools", pool2)

# Groups ---------

storageGroup = Storage()

group_details = StorageDetails()

hbaSpPair = HBASPPair()
hbaSpPair.hbaUid = "20:00:00:25:B5:00:00:2F:20:00:00:25:B5:00:00:0F"
hbaSpPair.controllerPortid = "0"
hbaSpPair.CONTROLLER = "emc b",
group_details.hbaSpPair = hbaSpPair

group_info = StorageInfo()
group_info.hostName = "fs_storage_3"
group_info.uuid = "08:90:F0:49:AA:3F:E4:11:B8:3F:00:60:16:6D:F2:D1"
group_info.devType = "STORAGE"
group_info.isVirtual = "1"
group_info.devSubType = "STORAGEGROUP"
group_info.vendor = "EMC CORPORATION"
group_info.platform = "VNX-BLOCK-OPERATING-ENVIRONMENT"
group_info.model = "VNX5200"
group_info.parents = "emcvnx1"

storageGroup.details = group_details
storageGroup.info = group_info

storageGroup.relatedEntities = {"HYPERVISOR": ["esxi-2.in.example.com"], "STORAGE": ["emcvnx1"]}
storage_map.map_component("storageGroups", storageGroup)


storageGroup2 = Storage()

group_details2 = StorageDetails()
hbaSpPair2 = HBASPPair()
hbaSpPair2.hbaUid = "20:00:00:25:B5:00:00:2F:20:00:00:25:B5:00:00:0F"
hbaSpPair2.controllerPortid = "1"
hbaSpPair2.CONTROLLER = "emc a",
group_details2.hbaSpPair = hbaSpPair2

group_info2 = StorageInfo()
group_info2.hostName = "storage4"
group_info2.uuid = "08:90:F0:49:AA:3F:E4:11:B8:3F:00:60:16:6D:F2:D2"
group_info2.devType = "STORAGE"
group_info2.isVirtual = "1"
group_info2.devSubType = "STORAGEGROUP"
group_info2.vendor = "EMC CORPORATION"
group_info2.platform = "VNX-BLOCK-OPERATING-ENVIRONMENT"
group_info2.model = "VNX5200"
group_info2.parents = "emcvnx1"

storageGroup2.details = group_details2
storageGroup2.info = group_info2

storageGroup2.relatedEntities = {"HYPERVISOR": ["esxi-2.in.example.com"], "STORAGE": ["emcvnx1"]}
storage_map.map_component("storageGroups", storageGroup2)

# --------

storage = Storage()

storage_info = StorageInfo()
storage_info.hostName = "emcvnx1"
storage_info.devType = "STORAGE"
storage_info.isVirtual = "0"
storage_info.devSubType = "STORAGE"
storage_info.vendor = "EMC CORPORATION"
storage_info.platform = "VNX-BLOCK-OPERATING-ENVIRONMENT"
storage_info.model = "VNX5200"
storage_info.version = "05.33.000.5.052"
storage_info.serialNumber = "APM00142413508"

storage.info = storage_info
storage_map.map_component("storage", storage)

# ------- Final Payload
payload = Payload()
info = Info()
info.ip_address = "198.51.100.21"
info.hostname = "emcvnx1"
info.device_type = "STORAGE"
info.device_subtype = "STORAGE"
info.serial_number = "APM00142413508"
info.platform = "VNX-BLOCK-OPERATING-ENVIRONMENT"
info.version = "05.33.000.5.052"

customer_info = CustomerInfo()
customer_info.site = "e0acbff9-37fe-4a5c-b89f-93330ef02c35:IND"
customer_info.organization = "a4770a0a-92cf-42e9-a7d8-d375b3892d8c:RESOLVE"

payload.info = info
payload.data = json.loads(storage_map.get_component_dict())
payload.customer_info = customer_info

print(payload.serialize())

Placeholder Usage

Placeholders allow you to substitute common values on the fly instead of entering them directly.

There are two categories of placeholders that you can use with custom device discovery:

  • Service account references
  • Reference to the IP address of a device

Service Account References

This category makes managing your custom device configurations easier. Instead of entering common authentication details multiple times, you can refer to an existing service account using these placeholders. This way, when you update the service account, all custom device configurations that refer to it will automatically update.

The category includes the following placeholders:

  • USER_NAME—Refers to the value of the service account's USERNAME field.
  • PASSWORD—Refers to the value of the service account's PASSWORD field.
  • PORT—Refers to the value of the service account's PORTS field. In case multiple port numbers are present, Insights gives each one a try until it makes a successful connection.

Go to Discovery and click the Service Accounts to create or edit service accounts.

IP Address Reference

This category includes a single placeholder that lets you refer to the list of IP addresses (IPv4 and IPv6) specified during discovery using the Discovery > Device Discovery > Local Discovery > Custom Configuration > FQDN/IP List option. It is useful, for example, to narrow down the list of devices returned by the custom device's discovery API.

  • IP_ADDRESS

Info Class

Set the following class properties to provide the device's basic description:

class Info(JsonSerializable):

def __init__(self):
self.ip_address = None
self.ipv6_address = None
self.hostname = None
self.fqdn = None
self.vendor = None
self.platform = None
self.platformType = None
self.version = None
self.serial_number = None
self.model = None
self.is_virtual = None
self.device_type = None
self.device_subtype = None
self.parents = None

ComputeDevice Class

Use this class to describe a device of type Compute.

class ComputeDevice(JsonSerializable):

def __init__(self):
self.vmDetailInfo = None
self.interfaces = None
self.dGatewayInfo = None
self.hostRoutingTable = None
self.services = None
self.processes = None
self.flows = None

NetworkDevice Class

Use this class to describe a device of type Network.

class NetworkDevice(JsonSerializable):

def __init__(self):
self.interfaces = None
self.ifxSwitchport = None
self.interfaces_mgmt0 = None
self.ifNameIndexMap = None
self.portChannelSummary = None
self.vmDetailInfo = None
self.ipMacFqdn = None
self.macAddressTable = None
self.interfaceNeighborsLLDP = None
self.interfaceNeighborsCDP = None
self.arpTable = None
self.vrfName = None
self.static = None

Storage Class

Use this class to describe a device of type Storage.

class Storage(JsonSerializable):
def __init__(self):
self.info = {}
self.details = {}
self.relatedEntities = {}
self.ifxInfo = []

StorageInfo Class

The info property of Storage is represented by the StorageInfo class:

class StorageInfo:
def __init__(self):
self.serialNumber = None
self.vendor = None
self.isVirtual = None
self.hostName = None
self.platform = None
self.devType = None
self.version = None
self.model = None
self.devSubType = None
self.discoveredIpAddr = None
self.reachableList = []
self.parents = []
self.uuid = None
self.lunId = None

StorageDetails Class

The details property of Storage is represented by the StorageDetails class. Only set the relevant properties when describing a device type.

class StorageDetails:
def __init__(self):
# Controllers
self.serialNumber = None
self.statisticsLogging = None
# Luns
self.storageGroups = None
self.currentUser = None
self.lunWwn = None
# Pools
self.raidType = None
self.lunList = []
self.boundDisks = []
# Ports
self.phyPortId = None
self.spName = None
# Storage Groups
self.hbaSpPair = []

MapStorage Class

The MapStorage class provides a couple of methods to allows you to build a map of the storage device's components.

class MapStorage(JsonSerializable):

def __init__(self):
self.STORAGE_COMPONENT_MAP = {"controllers": [], "luns": [], "storage": [], "ports": [], "pools": [],
"hosts": [], "storageGroups": [], "disks": [], "iogroups": [], "bricks": [],
"aggregates": [], "storagepools": [], "dynamicstoragepools": [], "volumes": [],
"enclosures": [], "filesystems": []}
self.component_list = self.STORAGE_COMPONENT_MAP.keys()

map_component()

Extends or appends a component:

  • If a new component name is specified, appends the component to the dictionary
  • If an existing component name is specified, extends the component in the dictionary
storage_map.map_component("controllers", controller)

get_component_dict()

Converts the storage dictionary to JSON.

payload.data = json.loads(storage_map.get_component_dict())

Detailed Data Classes

Use the following classed depending on the device type to specify the device's detailed data.

VmDetailInfo

Class Properties

Set the following class properties to provide information about the VM:

# Parameters to assign values in vmDetailInfo
class VmDetailInfo:

def __init__(self):
self.ipMacFqdn = None
self.coresPerSocket = None
self.cpuInfo = None
self.cpuMHz = None
self.cpuTotal = None
self.kernelVersion = None
self.memoryMB = None
self.mountedVolume = None
self.runningConfiguration = None

Class Methods

Adds a volume to the mounted volumes on the VM.

append_mounted_volume(value)

Interfaces

Set the following class properties to provide information about the machine's network interfaces:

class Interfaces(JsonSerializable):

def __init__(self):
self.alias = None
self.dGateway = None
self.description = None
self.ifxGlobalType = None
self.ifxLayerType = None
self.ifxName = None
self.ifxState = None
self.ifxVrf = None
self.ipv4Addr = None
self.ipv4Mask = None
self.ipv6Addr = None
self.isVirtual = None
self.linkState = None
self.networkUuid = None
self.normalize = None
self.pcGroupNumber = None
self.pcMode = None
self.phyAddr = None
self.portFcid = None
self.portNo = None
self.subIntDot1q = None
self.subIntParent = None
self.vlanList = []
self.vpcId = None
self.wwnn = None
self.wwpn = None
self.zoneName = None
self.bandwidth = None
self.vxlanPrimaryIp = None
self.vxlanSecondaryIp = None
self.adminDistance = None

DGateway

Set the following class properties to provide information about the default gateway:

class DGateway(JsonSerializable):

def __init__(self):
self.dgIpv4Addr = None
self.dgPhyAddr = None

HostRoutingTable

Set the following class properties to provide information about the host's routing table:

class HostRoutingTable(JsonSerializable):

def __init__(self):
self.destAddr = None
self.destMask = None
self.gateway = None
self.nextHopIfxName = None
self.nextHopIp = None

Services

Set the following class properties to provide information about processes running on the device:

class Services(JsonSerializable):

def __init__(self):
self.fsAppRole = None
self.fsService = None
self.ipAddress = None
self.isJVM = None
self.portPidMap = None
self.portSet = None
self.processIdSet = None
self.serviceName = None

Processes

Set the following class properties to provide information about the processes running on the machine:

class Processes(JsonSerializable):

def __init__(self):
self.normalized = None
self.serviceName = None

Flows

Set the following class properties to provide information about the service flows relating to the machine from the machine's perspective. These flows will be matched to the other sides of the flows to complete the flows.

class Flows(JsonSerializable):

def __init__(self):
self.destinationIp = None
self.connectionState = None
self.destinationPort = None
self.sourceServices = None
self.sourceIp = None
self.destinationServices = None

IfxSwitchport

Set the following class properties to provide information about the ports on a network switch:

class IfxSwitchport(JsonSerializable):

def __init__(self):
self.ifxLayerType = None
self.ifxName = None
self.ifxSwitchportMode = None
self.nativeVlan = None
self.normalize = None
self.vlanList = []

IfNameIndexMap

Set the following class properties to provide a map between the index and the name of an interface when using SNMP:

class IfNameIndexMap(JsonSerializable):

def __init__(self):
self.ifIndex = None
self.ifName = None

PortChannelSummary

Set the following class properties to describe the interfaces that are part of a port channel on a switch:

class PortChannelSummary(JsonSerializable):

def __init__(self):
self.ifxName = None
self.pcGroupNumber = None
self.pcMode = None

IpMacFqdn

Set the following class properties to provides the mapping between FQDN, IPv4 address, IPv6 address, and physical address on a device:

class IpMacFqdn(JsonSerializable):

def __init__(self):
self.fqdn = None
self.ipv4Addr = None
self.ipv6Addr = None
self.phyAddr = None

macAddressTable

Set the following class properties to provides a map between a MAC address and a switching interface on a network device:

class macAddressTable(JsonSerializable):

def __init__(self):
self.entryType = None
self.ifxName = None
self.ifxState = None
self.linkType = None
self.macAddress = None
self.neighborDeviceId = None
self.neighborIfxName = None
self.neighborName = None
self.normalize = None
self.vlanId = None

InterfaceNeighborsLLDP

Device information specific to Cisco devices.

class InterfaceNeighborsLLDP(JsonSerializable):

def __init__(self):
self.ifxName = None
self.neighborIfxIndex = None
self.neighborIfxName = None
self.neighborIpAddrList = None
self.neighborName = None
self.neighborPhyAddr = None
self.phyAddr = None

InterfaceNeighborsCDP

Device information specific to Cisco devices.

class InterfaceNeighborsCDP(InterfaceNeighborsLLDP):

def __init__(self):
super(InterfaceNeighborsCDP, self).__init__()

ArpTable

Set the following class properties to provide information about the ARP table of a device:

class ArpTable(JsonSerializable):

def __init__(self):
self.entryType = None
self.ifxName = None
self.linkType = None
self.macAddress = None
self.neighborIfxName = None
self.neighborName = None
self.vlanId = None

VrfName

Set the following class properties to provide information about a VRF routing table:

class VrfName(JsonSerializable):

def __init__(self):
self.exitIntf = None
self.ipAddress = None
self.phyAddress = None
self.vrfName = None

HBASPPair

Set the following class properties to provide a map between an HBA, a storage controller, and a controller port:

class HBASPPair:
def __init__(self):
self.hbaUid = None
self.CONTROLLER = None
self.controllerPortid = None

def append(self, value):
return value

ControllerInterfaces

Set the following class properties to provide information about the controller interfaces:

class ControllerInterfaces:
def __init__(self):
self.macAddress = None
self.wwnn = None
self.portStatus = None
self.wwpn = None
self.linkStatus = None
self.ifxName = None